﻿using System;
using System.Collections.Generic;
using Xunit;
using Xunit.Sdk;
using System.Reflection;

namespace SubSpec
{
	[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
	public class SpecificationAttribute : FactAttribute
	{
        protected override IEnumerable<ITestCommand> EnumerateTestCommands(IMethodInfo method)
        {
            try
            {
                RegisterSpecificationPrimitives(method);
                IEnumerable<ITestCommand> testCommands = SpecificationContext.ToTestCommands(method);

                return testCommands;
            }
            catch (Exception ex)
            {
                return new ITestCommand[] { new ExceptionTestCommand( method, ex ) };
            }
        }

        private static void RegisterSpecificationPrimitives( IMethodInfo method )
        {
            if (method.IsStatic)
                method.Invoke( null, null );
            else
            {
                ConstructorInfo defaultConstructor = method.MethodInfo.ReflectedType.GetConstructor( Type.EmptyTypes );

                if (defaultConstructor == null)
                    throw new InvalidOperationException( "Specification class does not have a default constructor" );

                object instance = defaultConstructor.Invoke( null );
                method.Invoke( instance, null );
            }
        }
    }
}